package com.jbookshelf.dal.providers;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.jbookshelf.dal.entities.*;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.primefaces.model.DualListModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public class PermissionsDataProviderImpl implements PermissionsDataProvider {

    @Autowired
    private SessionFactory sessionFactory;


    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public DualListModel<Permissions> getPermissions() {

        DualListModel<Permissions> dualResult = new DualListModel<Permissions>();

        dualResult.setSource(getAllPermissions());

        return dualResult;
    }


    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    private List<Permissions> getAllPermissions() {
        List<Permissions> result;

        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("from Permissions p");

        result = query.list();
        if (result.isEmpty()) return new ArrayList<Permissions>();
        else return result;
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public DualListModel<Permissions> getPermissions(int id) {
        DualListModel<Permissions> dualResult = new DualListModel<Permissions>();
        List<Permissions> resultTarget;
        List<Permissions> resultSource;

        resultTarget = getUserPermissions(id);
        resultSource = getAllPermissions();

        resultSource.removeAll(resultTarget);

        dualResult.setTarget(resultTarget);

        dualResult.setSource(resultSource);

        return dualResult;
    }

    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    private List<Permissions> getUserPermissions(int id) {
        Session session = sessionFactory.getCurrentSession();

        List<Permissions> result;

        String sql = "select up.permissions from UsersPermissions up where up.id.userId = :userID";

        Query query = session.createQuery(sql);

        query.setParameter("userID", id);

        result = query.list();
        if (result.isEmpty()) return new ArrayList<Permissions>();
        else return result;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    private boolean clearUsersPermissions(int userId) {
        Session session = sessionFactory.getCurrentSession();

        String sql = "delete from UsersPermissions up where up.id.userId = :userId";

        Query query = session.createQuery(sql);

        query.setParameter("userId", userId);

        if (query.executeUpdate() >= 0) {
            return true;
        } else
            return false;

    }

    @Override
    public void setPermission(Permissions permission) {
        // To change body of implemented methods use File | Settings | File
        // Templates.
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void setPermissions(List<Permissions> newPermissions, int userId) {

        Session session = sessionFactory.getCurrentSession();

        if (clearUsersPermissions(userId) != true) {
           // System.out.println("not delete userPermissions");
        }

        UsersPermissions userper;
        UsersPermissionsId userPerId;
        Date date = new Date();
        Users user = new Users();
        user.setId(userId);
        Users ownUser = new Users();
        ownUser.setId(Integer.valueOf(0));

        for (Permissions permissions : newPermissions) {
            userPerId = new UsersPermissionsId(userId, permissions.getId(),
                    date, Integer.valueOf(0));

            userper = new UsersPermissions(userPerId, user, ownUser,
                    permissions);

            session.save(userper);
        }

    }

    @Override
    public void deletePermission(Permissions permission) {
        // To change body of implemented methods use File | Settings | File
        // Templates.
    }

    @Override
    public void editPermission(Permissions permission) {
        // To change body of implemented methods use File | Settings | File
        // Templates.
    }


}
